package com.ruleengine.compiler.impl;


import com.ruleengine.compiler.ITaskCompiler;
import com.ruleengine.compiler.exception.CompilerException;
import com.ruleengine.instruction.InstructionManager;
import com.ruleengine.instruction.InstructionSet;
import com.ruleengine.instruction.InstructionType;
import com.ruleengine.instruction.impl.ConditionInstruction;
import com.ruleengine.instruction.impl.GotoInstruction;
import com.ruleengine.task.ITask;
import com.ruleengine.task.condition.ICondition;
import com.ruleengine.task.config.TaskConfigManager;
import com.ruleengine.task.impl.WhileTask;

public class WhileTaskCompiler extends BaseCompiler<WhileTask> {

    @Override
    public void comipleSubTask(WhileTask task, InstructionSet instSet)
            throws CompilerException {
        // TODO Auto-generated method stub
        //处理条件
        ICondition con = task.getCondition();
        //将条件表达式编译为条件指令
        ConditionInstruction conIn = InstructionManager.getInstance().createInstruction(InstructionType.CONDITION);
        conIn.setExpression(con.getExpression());
        instSet.addInstruction(conIn);

        //每个子指令开始位置
        int caseSize = instSet.size();
        
        //编译子任务
        ITask subTask = task.getSubTask(0);
        ITaskCompiler c = TaskConfigManager.getInstance().getTaskCompiler(
                subTask.getTaskType());
        c.comipleTask(subTask, instSet);
        
        //每条子指令长度
        int subSize =  instSet.size() - caseSize;
        
        //设置条件表达式的作用域
        conIn.setGotoOffset(subSize + 1);

        //处理附加的goto指令
        //这个goto指令用于while向前跳转，所以都是负数，而且要附件一个-1，用于抵消默认的指令+1
        GotoInstruction gotoIn = InstructionManager.getInstance().createInstruction(InstructionType.GOTO);
        gotoIn.setGotoOffset(-subSize - 1 - 1);
        instSet.addInstruction(gotoIn);

    }

}
